/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ac.pbp.dao.impl;

import ac.pbp.core.db.DaoHelper;
import ac.pbp.core.exception.DataAdditionException;
import ac.pbp.core.exception.DataDeletionException;
import ac.pbp.core.exception.DataModificationException;
import ac.pbp.core.filter.FilterCriteria;
import ac.pbp.dao.BukuDao;
import ac.pbp.dto.filter.BukuFilterCriteria;
import ac.pbp.model.Buku;
import ac.pbp.core.util.MyValidator;
import ac.pbp.model.BukuUser;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;

/**
 *
 * @author Kim
 */
@Component
public class BukuDaoImpl extends DaoHelper implements BukuDao {

    @Override
    public List<Buku> loadAll(Long start, Long max) {
        return getSession().createQuery("FROM Buku ORDER BY kodeBuku ASC").setCacheable(true).list();
    }

    @Override
    public List<Buku> filter(FilterCriteria filterCriteria) {
        BukuFilterCriteria filter = (BukuFilterCriteria) filterCriteria;
        Criteria criteria = filterRoot(filter, getSession().createCriteria(Buku.class));
        long start = (filter.getPage() - 1) * filter.getMax();
        criteria.setFirstResult(Long.valueOf(start).intValue());
        criteria.setMaxResults(Long.valueOf(filter.getMax()).intValue());
        return criteria.setCacheable(true).list();
    }

    @Override
    public Long getMax(FilterCriteria filterCriteria) {
        BukuFilterCriteria filter = (BukuFilterCriteria) filterCriteria;
        Criteria criteria = filterRoot(filter, getSession().createCriteria(Buku.class));
        return new Integer(criteria.setCacheable(true).list().size()).longValue();
    }

    @Override
    public Long getMax() {
        return (Long)getSession().createQuery("SELECT COUNT(*) FROM Buku").setCacheable(true).uniqueResult();
    }

    @Override
    public void add(Buku bean) throws DataAdditionException {
        try {
            getHibernateTemplate().save(bean);
        } catch (Exception e) {
            throw new DataAdditionException("Add New Buku Failed!", e);
        }
    }

    @Override
    public Buku load(String kodeBuku) {
        return (Buku) getSession().load(Buku.class, kodeBuku);
    }

    @Override
    public List<Buku> loadAll() {
        return getSession().createQuery("FROM Buku ORDER BY kodeBuku ASC").setCacheable(true).list();
    }

    @Override
    public void update(Buku bean) throws DataModificationException {
        try {
            getHibernateTemplate().update(bean);
        } catch (Exception e) {
            throw new DataModificationException("Update Buku Failed!", e);
        }
    }

    @Override
    public void delete(Buku bean) throws DataDeletionException {
        try {
            getHibernateTemplate().delete(bean);
        } catch (Exception e) {
            throw new DataDeletionException("Delete Buku Failed!", e);
        }
    }
    
    public Criteria filterRoot(BukuFilterCriteria filter, Criteria criteria) {
        criteria.addOrder(Order.asc("kodeBuku"));
        System.out.println("masuk filterRoot?");
        
        if (MyValidator.validateParam(filter.getDataSearch())) {
            criteria.add(Restrictions.disjunction()
                    .add(Restrictions.like("kodeBuku", filter.getDataSearch(), MatchMode.ANYWHERE))
                    .add(Restrictions.like("namaBuku", filter.getDataSearch(), MatchMode.ANYWHERE))
                    .add(Restrictions.like("descBuku", filter.getDataSearch(), MatchMode.ANYWHERE)));
        }
        
        return criteria;
    }
    
    @Override
    public List<Buku> getBukuByGenre(String genre) {
        
        return getSession().createSQLQuery("SELECT * FROM buku WHERE kode_genre like \"%" + genre + "%\"")
                .addEntity(Buku.class)
                .setCacheable(true)
                .list();
    }

    @Override
    public List<BukuUser> loadUserBuku(String kodeUser) {
        
        return getSession().createSQLQuery("SELECT * FROM buku_user WHERE kode_user = \"" + kodeUser + "\"      ")
                .addEntity(BukuUser.class)
                .setCacheable(true)
                .list();
    }

    @Override
    public List<Buku> loadBukuPengarang(String kodePengarang) {
        return getSession().createSQLQuery("SELECT * FROM buku WHERE kode_pengarang like \"%" + kodePengarang + "%\"")
                .addEntity(Buku.class)
                .setCacheable(true)
                .list();
    }

    @Override
    public List<Buku> loadNewestBooks() {
        return getSession().createSQLQuery("SELECT * FROM buku order by tgl_insert limit 5 ")
                .addEntity(Buku.class)
                .setCacheable(true)
                .list();
    }

    
}
